<?php

require_once 'BluesCoders/Context.php';
require_once 'BluesCoders/Context/Descriptor.php';
require_once 'BluesCoders/Loader/Standart.php';

/**
 * Description of Standart
 *
 * @author miho
 */



class BluesCoders_Context_Builder_Standart extends BluesCoders_Context{

    protected $_basePath;
    protected $_libraryFolderName = 'lib';

    public function  __construct(BluesCoders_Context $parent = null) {
        parent::__construct($parent);
    }

    public function getBean($id) {
        $bean = parent::getBean($id);

        if($bean instanceof BluesCoders_Context_Descriptor) {
            $bean = $this->createBean($bean);
            //$this->registerBean($id, $bean);
        }

        return $bean;
    }

    public function createBean(BluesCoders_Context_Descriptor $descriptor) {
        $class = $descriptor->getClass();

        if(! class_exists($class)) {
            try{
                $this->getLoader('defaultLoader')->load($class);
            }catch(Exception $e){
                if($this->_parent == null) {
                    throw $e;
                }else{
                    
                    $this->_parent->getLoader('defaultLoader')->load($class);
                }
            }
        }

        
        $bean = $this->createInstance($class, $descriptor->getConstructorArgs());

        $this->injectProperties($bean, $descriptor->getProperties());

        $this->_beans[$descriptor->getId()] = $bean;

        return $bean;
    }

    public function createInstance($class, $constructorArgs) {
        $reflection = new ReflectionClass($class);
        if($reflection->getConstructor())
            return $reflection->newInstanceArgs($constructorArgs);
        else
            return $reflection->newInstance();
    }

    public function injectProperties($bean, $properties) {
        foreach($properties as $name => $property) {
            $setterName = 'set'.ucfirst($name);
            if(method_exists($bean, $setterName)) {
                call_user_func(array($bean, 'set'.ucfirst($name)), $property);
            }else{
                throw new Exception(sprintf('class %s does not has property %s', get_class($bean), $name));
            }
        }
    }

    public function setBasePath($value) {
        $this->_basePath = $value;

        $loader = new BluesCoders_Loader_Standart();
        $loader->setPath($this->_basePath . DIRECTORY_SEPARATOR . $this->_libraryFolderName);
        $this->registerLoader('defaultLoader', $loader);


        return $this;
    }

}
?>
